# Плагины
Один из основных принципов Bevy является модульность. Все функции движка Bevy реализованы в виде плагинов. Это включает в себя такие встроенные функции, как рендер(средство визуляции), но игры сами по себе также являются реализованными плагинами! Это позволяет разработчикам самим выбирать, какие функции им нужны. Не нужен пользовательский интерфейс?. Не регистрируйте `UiPlugin`. Хотите построить «безголовый»(_headless_, без какой-либо графики) сервер? Не регистрируйте `RenderPlugin`.

Это также означает, что вы можете свободно заменять любые компоненты, который вам не нравятся. Если вы чувствуете необходимость, можете создать свой собственный плагин `UiPlugin`, но подумайте о том, [чтобы внести свой вклад в Bevy](https://bevyengine.org/learn/book/contributing), если считаете, что это было бы полезно!

# Стандартные плагины Bevy
Давайте сделаем наше приложение более интересным, добавив их. `add_plugins(DefaultPlugins)` добавляет те функции, которые большинство людей ожидают от движка, например, 2D/3D визуализатор, загрузка ассетов, система ПИ(пользовательский интерфейс), окна и ввод.

```rust
fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_startup_system(add_people)
        .add_system(hello_world)
        .add_system(greet_people)
        .run();
}
```

Снова запустите `cargo run`.

Вы должны заметить две вещи:

  * **Должно появится окно**. Это потому что мы сейчас имеем `WindowPlugin`, который определяет интерфейс окна (но только не знает, как окна делать), и `WinitPlugin`, который использует [библиотеку winit](https://github.com/rust-windowing/winit), для создания окна с использованием собственного оконного API вашей ОС.
  * **Ваша консоль теперь полна сообщений «hello»**: Это потому что `DefaultPlugins` добавляет «цикл событий»(_event loop_ [wiki](https://ru.wikipedia.org/wiki/%D0%A6%D0%B8%D0%BA%D0%BB_%D1%81%D0%BE%D0%B1%D1%8B%D1%82%D0%B8%D0%B9)) в ваше приложение. Расписание(`Shedule`) ECS нашего приложения теперь выполняется в цикле раз за «кадр». Скоро мы разберёмся со спамом в консоли.

Заметьте, что `add_plugins(DefaultPlugins)` эквивалетно следующему:

```rust
fn main() {
    App::new()
        .add_plugin(CorePlugin::default())
        .add_plugin(InputPlugin::default())
        .add_plugin(WindowPlugin::default())
        /* Дополнительные плагины опущены для краткости */
        .run();
}
```

Вы вольны использовать любой подход, который вам подходит!

# Создание вашего первого плагина
Для лучшей организации, давайте переместим всю нашу логику «hello» в плагин. Чтобы его создать, мы должны реализовать интерфейс `Plugin`. Добавьте следующий код в файл `main.rs`:

```rust
pub struct HelloPlugin;

impl Plugin for HelloPlugin {
    fn build(&self, app: &mut App) {
        // Добавьте всякого в ваше приложение здесь
    }
}
```

Теперь регистрируйте плагин в ваше приложение:

```rust
fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_plugin(HelloPlugin)
        .add_startup_system(add_people)
        .add_system(hello_world)
        .add_system(greet_people)
        .run();
}
```

Теперь всё что осталось, то переместить наши системы в `HelloPlugin`, всего лишь вырезать и вставить и вставить. Переменная `app` в функции `build()` нашего плагина — это тот же тип конструктора, который мы используем в нашей функции `main()`:

```rust
impl Plugin for HelloPlugin {
    fn build(&self, app: &mut App) {
        app.add_startup_system(add_people)
            .add_system(hello_world)
            .add_system(greet_people);
    }
}

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_plugin(HelloPlugin)
        .run();
}
```

